home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-11-29 | 63.5 KB | 1,463 lines |
- This document is intended to tell application authors how to write their
- applications so as to make use of the standard RISC OS printer driver
- interface. It starts with a general explanation of how the printer drivers
- are supposed to be used. Then the SWI interface is described and an example
- BASIC procedure is given that shows an application might do its printing. The
- final section of the document specifies exactly what VDU sequences and other
- plotting operations the application may use while printing.
-
-
-
- PRINTER DRIVER PHILOSOPHY
- =========================
-
-
- What the application user sees
- ------------------------------
-
- RISC OS comes with two printer driver applications, !PSPrinter for PostScript
- printers and !DMPrinter for a range of dot matrix printers.
-
- If I possess a PostScript printer and I wish to print, I should do the
- following:
-
- Double-click on !PSPrinter. An icon will appear. Menu on this and check
- that the settings are right for where the printer is connected, e.g.
- net/parallel/serial etc. This setting will be retained in CMOS RAM, so it
- need only be done once.
-
- If I wish to print Text files, drag them onto the printer icon. They will get
- printed.
-
- If I wish to print from ArcDraw, click Print on the Print dialogue box after
- running !PSPrinter. The diagram will be printed. Or, drag the icon from the
- Save dialogue box onto the printer icon.
-
- If I wish to print from ArcPaint, it's exactly the same.
-
- If I with to print from any other editor program, it's exactly the same.
-
- If I have a dot matrix printer, run !DMPrinter. Click on the printer icon to
- produce a dialogue box of the correct type of printer. Click on the
- printer-type field to cycle through the various dot matrix printers
- supported, until it reflects mine. If I can't find mine, seek help.
-
- Drivers for other printers will appear, from Acorn and from others, in an
- analogous form. New printer drivers will work with all existing applications,
- subject to the limitations of any particular printing device.
-
-
- How and Why
- -----------
-
- I use the term "editor" to mean any sort of interactive program that
- prepares, changes and processes data files. This includes word processors,
- DTP packages, spreadsheets, draw programs, etc. I use the term "Foo" to refer
- to any editor program, which operates on "Foo data files": so, substitute
- ArcDraw, ArcPaint, or whatever as you read. I use the term "Poo" to refer to
- any printer capable of generating graphics, e.g. FX80, Apple LaserWriter,
- etc.
-
- In the general case, editors save data in files of their own format, with an
- appropriate file type. Only Foo understands Foo data files. Also, different
- printers are entirely different from each other, and a pain to drive. If each
- editor is to understand each printer, and there are X editors and Y printers
- in the world, then:
-
- (a) There is X*Y work to do
- (b) If a new printer type comes along, all applications need updating.
-
- Because of this, RISC OS separates printer drivers from editors so that they
- are separate programs. This means:
-
- (a) There is X+Y work to do
- (b) If a new printer type comes along, once a printer driver has been
- written for it, it will work with all applications.
-
- This is clearly a better situation, and is one of the main reasons why
- applications working together is important.
-
- How do we achieve this? The main step is to define an interface that all
- editors should use when talking to printers, a sort of "virtual printer
- interface". All editors then output to this virtual interface, knowing little
- of the characteristics of the physical printer itself.
-
- The "virtual printer interface" chosen in RISC OS is to say that the printer
- supports a specified subset of the screen graphics primitives. This is
- because a WYSIWYG editor (where what you see on the screen is what you get on
- paper) will already contain code to render the data file using screen
- primitives; provided the application restricts itself to the specified
- subset, printing is unlikely to require very much extra code.
-
- There are several reasons why not all the screen primitives are supported by
- the virtual printer interface. The main ones are:
-
- (a) Some screen primitives are screen hardware specific (e.g. flashing
- colours, hardware palette changes, etc.).
- (b) Some screen primitives are very hard or impossible to implement on
- common types of printer (e.g. PostScript printers cannot handle
- non-overwriting GCOL actions).
- (c) Some screen primitives - e.g. flood fill - cannot be split across
- multiple boxes and so do not work with the window system. The printer
- drivers use a similar interface to the window system and have the same
- problems with these calls as it does.
-
- Each printer driver is implemented as a RISC OS relocatable module, which
- provides extra SWIs (system calls) concerned with starting, stopping and
- controlling a print job. The interface allows the printer driver to ask the
- application to render specific rectangles of the picture in any order, to
- give the printer driver maximum freedom in manipulating buffer space, etc.
-
- The interface to printer drivers means that an editor is not able to supply
- an acceptable user interface for setting printer-specific options such as
- quality/draft mode. For this reason, a separate application exists for each
- possible printer driver, to allow any printer-specific options to be set.
-
- The printing of plain text is such a basic facility that it is considered
- unacceptable to require the loading of ArcEdit. Furthermore, printers tend to
- provide a much simpler method for the printing of simple text than the
- facilities provided for arbitrary graphics. For this reason, every printer
- interface program provides simple facilities for the printing of plain text
- files.
-
-
-
- THE SWI INTERFACE
- =================
-
-
- To send output to the printer, an application must engage in a dialogue with
- the printer driver. Parts of this dialogue is similar to the dialogue with
- the window manager when a window requires redrawing. The dialogue can be
- summarised as follows:
-
- The application starts by opening a file to receive the printer driver's
- output. Typically this file is "printer:", but any file may be used. It
- passes this file's handle to SWI PDriver_SelectJob in order to start a print
- job.
-
- To output a page, the application then uses SWI PDriver_GiveRectangle to give
- the printer driver a list of the rectangles it wants to appear on the page
- and where it wants them to appear.
-
- When it has specified all the rectangles it wants printed, it uses SWI
- PDriver_DrawPage to ask the printer driver for the first rectangle to be
- printed. It then prints this rectangle and uses SWI PDriver_GetRectangle to
- get another rectangle to print, until there are no further rectangles to
- print. This is very similar to the way an application uses SWI
- Wimp_RedrawWindow and SWI Wimp_GetRectangle when redrawing its window.
-
- When all the desired pages have been output in this manner, the application
- first uses SWI PDriver_EndJob to end the print job, then closes the output
- file.
-
- The full set of printer driver SWIs is as follows:
-
-
- SWI PDriver_Info (&80140)
- -------------------------
-
- Entry: -
-
- Exit: R0 (top 16 bits) identifies general type of printer driven.
- Current assignments:
- 0 = PostScript printers.
- 1 = FX80 and similar dot matrix printers.
- R0 (bottom 16 bits) = 100 * version number of printer driver.
- R1 = X pixel resolution of printer driven (pixels/inch).
- R2 = Y pixel resolution of printer driven (pixels/inch).
- R3 = features word:
- Bit 0 set => colour
- If bit 0 set, bit 1 set => full colour range not available.
- Bit 2 set => only a discrete set of colours supported.
- Bit 8 set => cannot handle filled shapes well.
- Bit 9 set => cannot handle thick lines well.
- Bit 10 set => cannot handle overwriting well.
- Bit 24 set => supports the PDriver_ScreenDump call.
- Bit 25 set => supports arbitrary transformations (else only
- axis-preserving ones).
- R4 -> adjectival description of printers supported (a maximum of 20
- characters, excluding the zero-termination).
- R5 = X halftone resolution (repeats/inch). If no halftoning is done,
- this is equal to the value returned in R1.
- R6 = Y halftone resolution (repeats/inch). If no halftoning is done,
- this is equal to the value returned in R2.
- R7 identifies a specific configured printer. Assignments of these
- numbers are specific to each printer driver.
-
- Some of these values can be changed by the configuration application
- associated with the printer driver (using SWI PDriver_SetInfo). If SWI
- PDriver_Info is called while a print job is selected, the values returned are
- those that were in effect when that print job was started (i.e. when it was
- first selected using PDriver_SelectJob). If SWI PDriver_Info is called when
- no print job is active, the values returned are those that would be used for
- a new print job.
-
-
- SWI PDriver_SetInfo (&80141)
- ----------------------------
-
- Entry: R1 = X pixel resolution of printer driven (pixels/inch).
- R2 = Y pixel resolution of printer driven (pixels/inch).
- R3 (bit 0) is zero to set monochrome, 1 to set colour. The other
- bits of R3 are ignored.
- R5 = X halftone resolution (repeats/inch). If no halftoning is to be
- done, this should be equal to the value in R1.
- R6 = Y halftone resolution (repeats/inch). If no halftoning is to be
- done, this should be equal to the value in R2.
- R7 identifies a specific configured printer.
-
- Exit: -
-
- The configuration application associated with a particular printer driver
- uses this SWI to change the information values associated with subsequent
- print jobs. No other application should use this SWI.
-
-
- SWI PDriver_CheckFeatures (&80142)
- ----------------------------------
-
- Entry: R0 = features word mask.
- R1 = features word value.
-
- Exit: If the features word that PDriver_Info would return in R3 satisfies
- ((features word) AND R0) = (R1 AND R0), return is normal with all
- registers preserved. Otherwise a suitable error is generated, if
- appropriate - e.g. no error will be generated if the printer driver
- has the ability to support arbitrary rotations and your features
- word value merely requests axis-preserving ones.
-
- This call may be used by an application to check that the current printer
- driver has the features it requires, and to generate a suitable descriptive
- error if it doesn't.
-
-
- SWI PDriver_PageSize (&80143)
- -----------------------------
-
- Entry: -
-
- Exit: R1 = X size of paper, including margins. (Units 1/72000 inch)
- R2 = Y size of paper, including margins. (Units 1/72000 inch)
- R3 = left edge of printable area of paper, relative to the left edge
- of the paper. (Units 1/72000 inch)
- R4 = bottom edge of printable area of paper, relative to the bottom
- edge of the paper. (Units 1/72000 inch)
- R5 = right edge of printable area of paper, relative to the left
- edge of the paper. (Units 1/72000 inch)
- R6 = top edge of printable area of paper, relative to the bottom
- edge of the paper. (Units 1/72000 inch)
-
- An application can use this call to find out how big the paper in use is and
- how large the printable area on the paper is. This information can then be
- used to decide how to place the data to be printed on the page.
-
- These values can be changed by the configuration application associated with
- the printer driver (using SWI PDriver_SetPageSize). If SWI PDriver_PageSize
- is called while a print job is selected, the values returned are those that
- were in effect when that print job was started (i.e. when it was first
- selected using PDriver_SelectJob). If SWI PDriver_PageSize is called when no
- print job is active, the values returned are those that would be used for a
- new print job.
-
-
- SWI PDriver_SetPageSize (&80144)
- --------------------------------
-
- Entry: R1 = X size of paper, including margins. (Units 1/72000 inch)
- R2 = Y size of paper, including margins. (Units 1/72000 inch)
- R3 = left edge of printable area of paper, relative to the left edge
- of the paper. (Units 1/72000 inch)
- R4 = bottom edge of printable area of paper, relative to the bottom
- edge of the paper. (Units 1/72000 inch)
- R5 = right edge of printable area of paper, relative to the left
- edge of the paper. (Units 1/72000 inch)
- R6 = top edge of printable area of paper, relative to the bottom
- edge of the paper. (Units 1/72000 inch)
-
- Exit: -
-
- The configuration application associated with a particular printer driver
- uses this SWI to change the page size values associated with subsequent print
- jobs. No other application should use this SWI.
-
-
- SWI PDriver_SelectJob (&80145)
- ------------------------------
-
- Entry: R0 = file handle for print job to be selected, or zero to cease
- having any print job selected.
- R1 is zero or points to a title string for the job. This title
- string is terminated by any character outside the range ASCII
- 32-126.
-
- Exit: R0 = file handle for print job that was previously active, or zero
- if no print job was active.
-
- A print job is identified by a file handle, which must be that of a file that
- is open for output. The printer output for the job concerned is sent to this
- file.
-
- Calling SWI PDriver_SelectJob with R0=0 will cause the current print job (if
- any) to be suspended, and the printer driver will cease intercepting plotting
- calls.
-
- Calling SWI PDriver_SelectJob with R0 containing a file handle will cause the
- current print job (if any) to be suspended, and a print job with the given
- file handle to be selected. If a print job with this file handle already
- exists, it is resumed; otherwise a new print job is started. The printer
- driver will start to intercept plotting calls if it is not already doing so.
-
- Note that this call never ends a print job - to do so, use one of SWI
- PDriver_EndJob and SWI PDriver_AbortJob.
-
- The title string pointed to by R1 is treated by different printer drivers in
- different ways. It is only ever used if a new print job is being started, not
- when an old one is being resumed. Typical uses are:
-
- (a) A simple printer driver might ignore it.
- (b) The PostScript printer driver adds a line "%%Title: " followed by the
- given title string to the PostScript header it generates.
- (c) Printer drivers whose output is destined for an expensive central
- printer in a large organisation might use it when generating a cover
- sheet for the document.
-
- An application is always entitled not to supply a title (by setting R1=0),
- and a printer driver is entitled to ignore any title supplied.
-
- Printer drivers may also use the following OS variables when creating cover
- sheets, etc.:
-
- PDriver$For - indicates who the output is intended to go to.
- PDriver$Address - indicates where to send the output.
-
- These variables should not contain characters outside the range ASCII 32-126.
-
- If an error occurs during PDriver_SelectJob, the previous job will still be
- selected afterwards (though it may have been de-selected and re-selected
- during the call).
-
-
- SWI PDriver_CurrentJob (&80146)
- -------------------------------
-
- Entry: -
-
- Exit: R0 = file handle for print job that is currently active, or zero if
- no print job is active.
-
-
- SWI PDriver_FontSWI (&80147)
- ----------------------------
-
- This SWI is part of the internal interface between the font system and
- printer drivers. Applications should not call it.
-
-
- SWI PDriver_EndJob (&80148)
- ---------------------------
-
- Entry: R0 = file handle for print job to be ended.
-
- Exit: -
-
- This SWI should be used to end a print job normally. This may result in
- further printer output - e.g. the PostScript printer driver will produce the
- standard trailer comments.
-
- If the print job being ended is the currently active one, there will be no
- current print job after this call (so plotting calls will no longer be
- intercepted).
-
- If the print job being ended is not currently active, it will be ended
- without altering which print job is currently active or whether plotting
- calls are being intercepted.
-
-
- SWI PDriver_AbortJob (&80149)
- -----------------------------
-
- Entry: R0 = file handle for print job to be aborted.
-
- Exit: -
-
- This SWI should be used to end a print job abnormally - it should generally
- be called after fatal errors while printing. It will not try to produce any
- further printer output - this is important if an error occurs while sending
- output to the print job's output file.
-
- If the print job being aborted is the currently active one, there will be no
- current print job after this call (so plotting calls will no longer be
- intercepted).
-
- If the print job being aborted is not currently active, it will be aborted
- without altering which print job is currently active or whether plotting
- calls are being intercepted.
-
-
- SWI PDriver_Reset (&8014A)
- --------------------------
-
- Entry: -
-
- Exit: -
-
- This SWI aborts all print jobs known to the printer driver, leaving the
- printer driver with no active or suspended print jobs and ensuring that
- plotting calls are not being intercepted.
-
- Normal applications shouldn't use this SWI, but it can be useful as an
- emergency recovery measure when developing an application.
-
- A call to this SWI is generated automatically if the machine is reset or the
- printer driver module is killed or RMTIDYed.
-
-
- SWI PDriver_GiveRectangle (&8014B)
- ----------------------------------
-
- Entry: R0 = rectangle identification word. This word is reported back to
- the application when it is requested to plot all or part of
- this rectangle.
- R1 -> 4 word block, containing rectangle to be plotted. Units are OS
- units.
- R2 -> 4 word block, containing dimensionless transformation to be
- applied to the specified rectangle before printing it. The
- entries are given as fixed point numbers with 16 binary places,
- so the transformation is:
- x' = (x * R2!0 + y * R2!8)/2^16
- y' = (x * R2!4 + y * R2!12)/2^16
- R3 -> 2 word block, containing the position where the bottom left
- corner of the rectangle is to be plotted on the printed page.
- Units are 1/72000 inch.
- R4 = background colour for this rectangle, in the form &BBGGRRXX.
-
- Exit: -
-
- This SWI allows an application to specify a rectangle from its workspace to
- be printed, how it is to be transformed and where it is to appear on the
- printed page. An application should make one or more calls to SWI
- PDriver_GiveRectangle before a call to SWI PDriver_DrawPage and the
- subsequent calls to SWI PDriver_GetRectangle. (Multiple calls allow the
- application to print multiple rectangles from its workspace to one printed
- page - e.g. for "two up" printing).
-
- The printer driver may subsequently ask the application to plot the specified
- rectangles or parts thereof in any order it chooses. An application should
- not make any assumptions about this order or whether the rectangles it
- specifies will be split. (A common reason why a printer driver might split a
- rectangle is that it prints the page in strips to avoid using excessively
- large page buffers.)
-
- Assuming that a non-zero number of copies is requested and that none of the
- requested rectangles go outside the area available for printing, it is
- certain to ask the application to plot everything requested at least once. It
- may ask for some areas to be plotted more than once, even if only one copy is
- being printed, and it may ask for areas marginally outside the requested
- rectangles to be plotted (this can typically happen if the boundaries of the
- requested rectangles are not on exact device pixel boundaries).
-
- If SWI PDriver_GiveRectangle is used to specify a set of rectangles that
- overlap on the output page, the rectangles will be printed in the order of
- the SWI PDriver_GiveRectangle calls. For appropriate printers (i.e. most
- printers, but not e.g. XY plotters), this means that rectangles supplied via
- later PDriver_GiveRectangle calls will overwrite rectangles supplied via
- earlier calls.
-
-
- SWI PDriver_DrawPage (&8014C)
- -----------------------------
-
- Entry: R0 = number of copies to print.
- R1 -> 4 word block, to receive the rectangle to print.
- R2 is zero or contains the page's sequence number within the
- document being printed (i.e. 1-n for an n-page document).
- R3 is zero or points to a string, terminated by a character in the
- ASCII range 33-126 (note spaces are not allowed), which gives
- the 'real' page number. (Examples: "23", "viii", "A-1")
-
- Exit: R0 = number of copies still requiring printing. This is zero if and
- only if no more plotting is required.
- If R0 is non-zero, the area pointed to by R1 has been filled in with
- the rectangle that needs to be plotted, and R2 contains the
- rectangle identification word for the user-specified rectangle
- that this is a part of.
- If R0 is zero, the contents of R2 and the area pointed to by R1 are
- undefined.
-
- This SWI should be called after all rectangles to be plotted on the current
- page have been specified (using SWI PDriver_GiveRectangle). It returns the
- first rectangle that the printer driver wants plotted in the area pointed to
- by R1. If nothing requires plotting - i.e. if there is no such rectangle - it
- returns R0=0.
-
- So the application should stop trying to plot the current page if R0=0, and
- continue otherwise. If R0<>0, the fact that R0 is the number of copies still
- to be printed is only intended to be used for information purposes (e.g.
- putting a "Printing page m of n" message on the screen); as long as it is
- non-zero, R0's value does not affect what the application should try to plot.
-
- The information passed in R2 and R3 is not particularly important, though it
- helps to make output produced by the PostScript printer driver conform better
- to Adobe's structuring conventions. If non-zero values are supplied, they
- should be correct. Note that R2 is NOT the sequence number of the page in the
- print job, but in the document.
-
- An example: if a document consists of 11 pages, numbered "" (the title page),
- "i"-"iii" and "1"-"7", and the application is requested to print the entire
- preface part, it should use R2 = 2, 3, 4 and R3 -> "i", "ii", "iii" for the
- three pages.
-
- When plotting starts in a rectangle supplied by a printer driver, the printer
- driver behaves as though the VDU system is in the following state:
-
- * VDU drivers enabled.
- * VDU 5 state has been set up.
- * all graphics cursor positions and the graphics origin have been set to
- (0,0).
- * the current dot pattern for dotted lines plotted via VDU calls is
- &AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA, with a repeat length of 8.
- * a VDU 5 character size and spacing of 16 OS units by 32 OS units.
- * the graphics clipping region has been set to bound the actual area that
- is to be plotted. (But note that an application cannot read what this
- area is: the printer drivers do not - and cannot - intercept
- OS_ReadVduVariables or OS_ReadModeVariable.)
- * the area in which plotting will actually take place has been cleared to
- the background colour supplied in the corresponding PDriver_GiveRectangle
- call, as though a CLG had occurred.
- * the cursor movement control bits (i.e. the ones that would be set by
- VDU 23,16,...) are set to &40 - i.e. cursor movement is normal, except
- that movements beyond the edge of the graphics window in VDU 5 mode do
- not generate special actions.
- * one OS unit on the paper is 1/180 inch.
-
- This is designed to be as similar as possible to the state set up by the
- window manager when redrawing.
-
-
- SWI PDriver_GetRectangle (&8014D)
- ---------------------------------
-
- Entry: R1 -> 4 word block, to receive the rectangle to print.
-
- Exit: R0 = number of copies still requiring printing. This is zero if and
- only if no more plotting is required.
- If R0 is non-zero, the area pointed to by R1 has been filled in with
- the rectangle that needs to be plotted, and R2 contains the
- rectangle identification word for the user-specified rectangle
- that this is a part of.
- If R0 is zero, the contents of R2 and the area pointed to by R1 are
- undefined.
-
- This SWI should be used after plotting a rectangle returned by a previous
- call to SWI PDriver_DrawPage or SWI PDriver_GetRectangle, to get the next
- rectangle the printer driver wants plotted. It returns precisely the same
- information as PDriver_DrawPage.
-
-
- SWI PDriver_CancelJob (&8014E)
- ------------------------------
-
- Entry: R0 = file handle for job to be cancelled.
-
- Exit: -
-
- This SWI causes subsequent attempts to output to the print job associated
- with the given file handle to do nothing other than generate the error "Print
- job cancelled". An application is expected to respond to this error by
- aborting the print job.
-
-
- SWI PDriver_ScreenDump (&8014F)
- -------------------------------
-
- Entry: R0 = file handle of file to receive the dump.
-
- Exit: -
-
- If this SWI is supported (i.e. if bit 24 is set in the value SWI PDriver_Info
- returns in R3), this SWI causes the printer driver to output a screen dump to
- the file handle supplied in R0. The file concerned should be open for output.
- If the SWI is not supported, an error is returned.
-
-
- SWI PDriver_EnumerateJobs (&80150)
- ----------------------------------
-
- Entry: R0 = 0 to get file handle of first print job, or file handle of a
- print job to get the file handle of the next print job.
- Exit: R0 = file handle of print job requested, or 0 if there are no more
- print jobs.
-
- This allows the print jobs that exist to be enumerated. The order in which
- they appear is undefined.
-
-
- SWI PDriver_SetPrinter (&80151)
- -------------------------------
-
- Entry: Printer-driver specific.
- Exit: Printer-driver specific.
-
- This allows the setting of options specific to a particular printer driver.
- See the individual printer driver documentation for details.
-
-
-
- EXAMPLE BASIC PROCEDURE
- =======================
-
-
- An example BASIC procedure that does a standard "two up" printing job:
-
- DEFPROCprintout(firstpage%, lastpage%, title$, filename$)
- :
- REM Get SWI numbers used in this procedure.
- LOCAL select%, abort%, pagesize%, giverect%, drawpage%, getrect%, end%
- SYS "OS_SWINumberFromString",,"PDriver_SelectJob" TO select%
- SYS "OS_SWINumberFromString",,"PDriver_AbortJob" TO abort%
- SYS "OS_SWINumberFromString",,"PDriver_PageSize" TO pagesize%
- SYS "OS_SWINumberFromString",,"PDriver_GiveRectangle" TO giverect%
- SYS "OS_SWINumberFromString",,"PDriver_DrawPage" TO drawpage%
- SYS "OS_SWINumberFromString",,"PDriver_GetRectangle" TO getrect%
- SYS "OS_SWINumberFromString",,"PDriver_EndJob" TO end%
- :
- REM Open destination file and set up a local error handler that will
- REM close it again on an error.
- LOCAL H%, O%
- H% = OPENOUT(filename$)
- LOCAL ERROR
- ON ERROR LOCAL:RESTORE ERROR:CLOSE#H%:PROCpasserror
- :
- REM Start up a print job associated with this file, remembering the
- REM handle associated with the previous print job (if any), then set up a
- REM a local error handler for it.
- SYS select%,H%,title$ TO O%
- LOCAL ERROR
- ON ERROR LOCAL:RESTORE ERROR:SYSabort%,H%:SYSselect%,O%:PROCpasserror
- :
- REM Now we decide how two pages are to fit on a piece of paper.
- LOCAL left%, bottom%, right%, top%
- PROCgetdocumentsize(box%)
- SYS pagesize% TO ,,,left%,bottom%,right%,top%
- PROCfittwopages(left%,bottom%,right%,top%,box%,matrix%,origin1%,origin2%)
- :
- REM Start the double page loop
- LOCAL page%, copiesleft%, pagetoprint%, white%
- white%=&FFFFFF00
- FOR page%=firstpage% TO lastpage% STEP 2
- :
- REM Set up to print two pages, or possibly just one last time around.
- SYS giverect%, page%, box%, matrix%, origin1%, white%
- IF page%<lastpage% THEN
- SYS giverect%, page%+1, box%, matrix%, origin2%, white%
- ENDIF
- :
- REM Start printing. As each printed page corresponds to two document
- REM pages, we cannot easily assign any sensible page numbers to printed
- REM pages. So we simply pass zeroes to PDriver_DrawPage.
- SYS drawpage%,1,box2%,0,0 TO copiesleft%,,pagetoprint%
- WHILE copiesleft%<>0
- PROCprintpage(pagetoprint%, box2%)
- SYS getrect%,,box% TO copiesleft%,,pagetoprint%
- ENDWHILE
- :
- REM End of page loop
- NEXT
- :
- REM All pages have now been printed. Terminate this print job.
- SYS end%,H%
- :
- REM Go back to the first of our local error handlers.
- RESTORE ERROR
- :
- REM And go back to whatever print job was active on entry to this
- REM procedure (or to no print job in no print job was active).
- SYS select%,O%
- :
- REM Go back to the caller's error handler.
- RESTORE ERROR
- :
- REM Close the destination file.
- CLOSE#H%
- ENDPROC
- :
- DEFPROCpasserror
- ERROR ERR,REPORT$+" (from line "+STR$(ERL)+")"
- ENDPROC
-
- This uses the following global areas of store:
-
- box%: 4 words
- box2%: 4 words
- matrix%: 4 words
- origin1%: 2 words
- origin2%: 2 words
-
- And the following external procedures:
-
- DEFPROCgetdocumentsize(box%)
- - fills the area pointed to by 'box%' with the size of a document page in
- OS units.
-
- DEFPROCfittwopages(l%, b%, r%, t%, box%, transform%, org1%, org2%)
- - given left, bottom, right and top bounds of a piece of paper in units of
- 1/72000 inch, and a bounding box of a document page in OS units, sets up
- a transformation and two origins in the areas pointed to by 'tr%','org1%'
- and 'org2%' to print two of those pages on a piece of paper.
-
- DEFPROCdrawpage(page%, box%)
- - draw the parts of document page number 'page%' that lie with the box held
- in the 4 word area pointed to by 'box%'.
-
- If printing is likely to take a long time and the application does not want
- to hold other applications up while it prints, it should regularly use a
- sequence like the following during printing:
-
- SYS select%,O%
- SYS "Wimp_Poll",mask%,area% TO reason%
- <process reason% as appropriate>
- SYS select%,H% TO O%
-
-
-
- THE VIRTUAL PRINTER INTERFACE
- =============================
-
-
- When a print job is active, the printer driver intercepts the following
- vectors:
-
- (a) WrchV (= WriteCV): all character output is received and interpreted by
- the printer driver. Many VDU sequences are converted into printer
- output to do similar things on the printed page. Some VDU sequences
- produce errors. A few are passed through to the real VDU drivers. Only
- these last go through the usual output stream selection controlled by
- OS_Byte 3.
- See the section entitled 'VDU SEQUENCES' below for more details.
-
- (b) SpriteV: most sprite operations are passed on unchanged to the
- SpriteExtend module and/or the operating system. Those that do sprite
- plotting are intercepted and generate printer output to do similar
- sprite plotting on the printed page.
- Note that, because of the way vector interception is done, the
- SpriteExtend module must be initialised before the printer driver.
- See the section entitled 'SPRITE OPERATIONS' below for more details.
-
- (c) DrawV: Draw calls that would not normally plot to the screen are passed
- on unchanged to the Draw module. Others are intercepted and, where
- possible, used to generate printer output to do similar things on the
- printed page. However, some of the intercepted calls cannot be so
- treated and instead produce errors.
- Note that, because of the way vector interception is done, the
- Draw module must be initialised before the printer driver.
- See the section entitled 'DRAW MODULE CALLS' below for more details.
-
- (d) ColourV: some ColourTrans calls are intercepted and processed by the
- printer driver, others are left to be dealt with by the ColourTrans
- module itself.
- Note that, because of the way vector interception is done, the
- ColourTrans module must be initialised before the printer driver.
- See the section entitled 'COLOURTRANS MODULE CALLS' below for more
- details.
-
- (e) ByteV: The OS_Byte calls dealing with dot-dash repeat lengths (OS_Byte
- 163,242,0-64) are intercepted and processed by the printer driver. The
- same applies to OS_Byte 218 (read/write bytes in VDU queue).
- See the section entitled 'MISCELLANEOUS CALLS' below for more
- details.
-
- In addition, the font manager and the printer driver interact to cause many
- of the font manager calls to be processed by the printer driver. See the
- section entitled 'FONT MANAGER CALLS' below for more details.
-
-
-
- VDU SEQUENCES
- =============
-
-
- General rules
- -------------
-
- Whenever a print job is active, the printer driver will intercept all
- characters sent through WrchV. It will then queue them in the same way as the
- VDU drivers do and process complete VDU sequences as they appear. Because the
- printer driver will not pick up any data currently in the VDU queue, and may
- send sequences of its own to the VDU drivers, a print job should not be
- selected with an incomplete sequence in the VDU queue.
-
- Also, because the printer driver may send sequences of its own to the VDU
- drivers, the output stream specification set by OS_Byte 3 should be in its
- standard state (i.e. as though set by OS_Byte 3,0).
-
- The printer driver will pass the following VDU sequences through to the
- normal VDU drivers, either because they control the screen hardware or
- because they affect global resources such as the character and ECF
- definitions:
-
- VDU 7 - Produce bell sound
- VDU 19,l,p,r,g,b - Change hardware palette
- VDU 20 - Set default hardware palette
- VDU 23,0,n,m| - "Program 6845 registers"
- VDU 23,1,n| - Change cursor appearance
- VDU 23,2-5,a,b,c,d,e,f,g,h - Set ECF pattern
- VDU 23,9-10,n| - Set flash durations
- VDU 23,11| - Set default ECF patterns
- VDU 23,12-15,a,b,c,d,e,f,g,h - Simple setting of ECF pattern
- VDU 23,17,4,m| - Set ECF type
- VDU 23,17,6,x;y;| - Set ECF origin
- VDU 23,32-255,a,b,c,d,e,f,g,h - Define character
-
- The printer driver will interpret or fault all other VDU sequences. If the
- printer driver currently wants a rectangle printed (i.e. if there has been a
- call to SWI PDriver_DrawPage or SWI PDriver_GetRectangle and the last such
- call returned R0 <> 0), these will result in it producing appropriate output
- or errors. Otherwise, the printer driver will keep track of some state
- information (e.g. what the current foreground and background colours are),
- but will not produce any printer output.
-
- The printer driver will always behave as though it is in VDU 5 state. No text
- co-ordinate system is defined, and no scrolling is possible. For these
- reasons, the following VDU sequences are faulted:
-
- VDU 4 - exit VDU 5 state
- VDU 23,7,m,d,z| - scroll display
- VDU 23,8,t1,t2,x1,y1,x2,y2| - clear text block
-
- It is generally meaningless to try to send or echo characters directly to the
- printer while printing. Furthermore, attempts to do so are likely to disrupt
- the operation of printer drivers. For these reasons, the following VDU
- sequences are faulted:
-
- VDU 1,c - send character to printer
- VDU 2 - start echoing characters to printer
-
- It is not possible to change the "mode" of a printed page, so the following
- VDU sequence is faulted:
-
- VDU 22,m - change display mode
-
- A printer driver cannot be written to deal with undefined or reserved calls,
- so the following VDU sequences are faulted:
-
- VDU 23,18-24,... - reserved for Acorn expansion
- VDU 23,28-31,... - reserved for use by applications
- VDU 25,216-231,... - reserved for Acorn expansion
- VDU 25,240-255,... - reserved for use by applications
-
- The following VDU sequences are ignored, either because they normally do
- nothing (at least when stuck in VDU 5 mode and not echoing characters to the
- printer) or because they have no sensible interpretation when applied to
- printed output rather than a screen.
-
- VDU 0 - do nothing
- VDU 3 - stop echoing characters to printer
- VDU 5 - enter VDU 5 state
- VDU 14 - start "paged" display
- VDU 15 - end "paged" display
- VDU 17,c - define text colour
- VDU 23,17,5| - exchange text foreground and background
- VDU 27 - do nothing
- VDU 28,l,b,r,t - define text window
-
-
- Colours
- -------
-
- Colours are a rather complicated matter. It is strongly recommended that
- applications should use SWI ColourTrans_SetGCOL, SWI ColourTrans_SelectTable
- and SWI ColourTrans_SetFontColours to set colours, as these will allow the
- printer to produce as accurate an approximation as it can to the desired
- colour, independently of the screen palette. The GCOL sequence (VDU 18,k,c)
- should only be used if absolutely necessary, and the application writer
- should be aware of the fact that the printer driver has a simplified
- interpretation of the parameters, as follows:
-
- * The fact that the background colour is affected if c >= 128 and the
- foreground colour if c < 128 is unchanged.
- * If k MOD 8 <> 0, subsequent plots and sprite plots will not do anything.
- * If k=0, subsequent plots will cause the colour c MOD 128 (possibly
- modified by the current tint) is looked up in the screen palette (at the
- time of plotting, not the time the VDU 18,k,c command was issued).
- Plotting is done by overwriting with the closest approximation the
- printer can produce to the RGB combination found. Subsequent sprite
- plotting will be done without use of the sprite's mask.
- * If k=8, subsequent plots will be treated the same as k=0 above, except
- that sprite plots will be done using the sprite's mask (if any).
- * If k=16 or k=24, ECF pattern 1 will be read (at the time of plotting).
- Each pixel value in it will be looked up as an RGB combination in the
- screen's palette, and the resulting values will be averaged. Plotting
- will be done with the closest approximation the printer can produce to
- the resulting colour. Sprite plotting is done without using the sprite's
- mask if k=16 and using it if k=24.
- * The cases k=32 and k=40 are treated similarly to k=16 and k=24, except
- that ECF pattern 2 is used.
- * The cases k=48 and k=56 are treated similarly to k=16 and k=24, except
- that ECF pattern 3 is used.
- * The cases k=64 and k=72 are treated similarly to k=16 and k=24, except
- that ECF pattern 4 is used.
- * The cases k=80 and k=88 are treated similarly to k=16 and k=24, except
- that the "giant" ECF pattern is used.
-
- The major problems with the use of VDU 18,k,c to set colours are (a) that
- it makes the printer driver output dependent on the current screen mode and
- palette; (b) that it artificially limits the printer driver to the number
- of colours displayed on the screen (which can be very limiting in a two
- colour mode!).
-
- Other techniques that depend on GCOLs (e.g. SWI Font_SetFontColours,
- colour-changing sequences in strings passed to Font_Paint, plotting sprites
- without a translation table, etc.) have the same problems and are similarly
- not recommended.
-
- No operations other than overwriting are permitted, mainly because they
- cannot be implemented on many common printers (e.g. PostScript printers).
-
- The treatment of ECF patterns is only intended to allow them to be used to
- "mix" colours. (Allowing genuine pattern printing is a possible area for
- future printer driver development.)
-
- Note that the printer driver maintains its own foreground and background
- colour information. The screen foreground and background colours are not
- affected by VDU 18,k,c sequences encountered while a print job is active.
-
- Similarly, VDU 23,17,2-3,t| sequences encountered while a print job is active
- do not affect the screen tints, just the printer driver's own tints. VDU
- 23,17,0-1,t| sequences would only affect the colours of the text tints, so
- the printer driver ignores them.
-
-
- Other graphics state operations
- -------------------------------
-
- The VDU 6 and VDU 21 sequences have their normal effects of enabling and
- disabling execution (but not parsing) of subsequent VDU sequences. As usual,
- the printer driver keeps track of this independently of the VDU drivers.
-
- The cursor movement VDU sequences (i.e. VDU 8-11, VDU 13, VDU 30 and VDU
- 31,x,y) all update the current graphics position (without updating the
- previous graphics positions used in e.g. triangle plotting), precisely as
- they do in VDU 5 mode on the screen.
-
- VDU 24,l;b;r;t; will set the printer driver's graphics clipping box. The
- rectangle specified should lie completely within the box that was reported on
- return from the last call to SWI PDriver_DrawPage or SWI
- PDriver_GetRectangle. If this is not the case, it is not defined what will
- happen, and different printer drivers may treat it in different ways. This is
- analogous to the situation with the window manager: attempts to set a
- graphics clipping box outside the rectangle currently being redrawn may be
- ignored completely (if they go outside the screen) or may get obeyed (with
- consequences that are almost certainly wrong!).
-
- VDU 29,x;y; sets the printer driver's graphics origin.
-
- VDU 26 will reset the printer driver's graphics clipping box to its maximum
- size (this is essentially the box reported on return from the last call to
- SWI PDriver_DrawPage or SWI PDriver_GetRectangle, but may be slightly
- different due to rounding problems when converting from a box expressed in
- printer pixels to one expressed in OS units). It also resets its versions of
- the graphics origin, the current graphics position and all the previous
- graphics positions to (0,0).
-
- VDU 23,6,a,b,c,d,e,f,g,h will set the printer driver's current dot pattern
- (for use with lines plotted via VDU 25,16-31,x;y; and VDU 25,48-63,x;y;). The
- exact lengths of the dashes and gaps produced may differ between various
- printer drivers, and also between the screen and printer drivers, so an
- application should not rely on them. However, an application can reasonably
- expect each set bit in the pattern to correspond to approximately 2 to 3 OS
- units on the printed page.
-
- VDU 23,16,x,y| changes the printer driver's version of the cursor control
- flags, and thus how the cursor movement control sequences and BBC-style
- character plotting affect the current graphics position. As usual, this is
- completely independent of the corresponding flags in the VDU drivers.
- However, printer drivers pay no attention to the setting of bit 6 (which
- controls whether movements beyond the edge of the graphics window cause
- carriage return/line feeds and other cursor movements to be generated
- automatically) - they always behave as though it is set. Note that the
- Wimp normally sets this bit, and that it is not sensible to have it clear
- at any time during a Wimp redraw.
-
- VDU 23,17,7,flags,x;y;| changes the printer driver's version of the size that
- BBC-style characters are to be plotted and the spacing that is required
- between them. Setting the VDU 4 character size cannot possibly affect the
- printer driver's output and so will be ignored completely. As noted below
- under 'Plotting operations', a "pixel" is regarded as the size of a screen
- pixel for the screen mode that was in effect when the print job was started.
-
-
- Plotting operations
- -------------------
-
- The printer driver regards a "pixel" as having size 2 OS units square (1/90
- inch square). The main effect of this is that all PLOT line, PLOT point and
- PLOT outline calls will produce lines that are approximately 2 OS units
- wide.
-
- However, when translating the character size and spacing information provided
- by VDU 23,17,7,... (see above) from pixels to OS units, the screen pixel size
- for the screen mode that was in effect when the print job was started is
- used. This is done in the expectation that the application is basing its
- requested sizes on that screen mode.
-
- The following VDU sequences perform straightforward plotting operations;
- printer drivers will produce the corresponding printed output:
-
- VDU 12 - clear graphics window (in VDU 5 state)
- VDU 16 - clear graphics window
- VDU 25,0-63,x;y; - draw line
- VDU 25,64-71,x;y; - draw point
- VDU 25,80-87,x;y; - fill triangle
- VDU 25,96-103,x;y; - fill axis-aligned rectangle
- VDU 25,112-119,x;y; - fill parallelogram
- VDU 25,144-151,x;y; - draw circle
- VDU 25,152-159,x;y; - fill circle
- VDU 25,160-167,x;y; - draw circular arc
- VDU 25,168-175,x;y; - fill circular segment
- VDU 25,176-183,x;y; - fill cicular sector
- VDU 25,192-199,x;y; - draw ellipse
- VDU 25,200-207,x;y; - fill ellipse
- VDU 32-126 - print characters in BBC-style font
- VDU 127 - backspace & delete
- VDU 128-255 - print characters in BBC-style font
-
- One difference to note is that most printer drivers will either not do the
- rounding to pixel centres normally done by the VDU drivers, or will round to
- different pixel centres (probably the centres of their device pixels).
-
- The following VDU sequences are faulted because they cannot be split up
- easily across rectangles, and also because they depend on the current picture
- contents and so cannot be implemented e.g. on PostScript printers:
-
- VDU 25,72-79,x;y; - horizontal line fill (flood fill primitive)
- VDU 25,88-95,x;y; - horizontal line fill (flood fill primitive)
- VDU 25,104-111,x;y; - horizontal line fill (flood fill primitive)
- VDU 25,120-127,x;y; - horizontal line fill (flood fill primitive)
- VDU 25,128-143,x;y; - flood fills
- VDU 25,184-191,x;y; - copy/move rectangle
-
- Exception: VDU 25,184,x;y; and VDU 25,188,x;y; are now correctly interpreted
- by printer drivers (as being equivalent to VDU 25,0,x;y; and VDU 25,4,x;y;
- respectively).
-
- The sprite plotting sequences (VDU 23,27,m,n| and VDU 25,232-239,x;y;) are
- converted to the appropriate calls to SWI OS_SpriteOp. These calls will then
- be intercepted as normal by the printer driver (see under 'SPRITE OPERATIONS'
- below). In addition, the VDU 25,232-239,x;y; sequence causes the printer
- driver's graphics position to be updated. Application writers should use
- direct calls to SWI OS_SpriteOp in preference to these sequences.
-
- The font manager VDU sequences (VDU 23,25,a,b,c,d,e,f,g,h,
- VDU 23,26,a,b,c,d,e,f,g,h,text and VDU 25,208-215,x;y;text) are trapped by
- the printer driver and converted into the corresponding font manager SWIs.
- These are then handled as normal (see under 'FONT MANAGER CALLS' below). In
- addition, the VDU 25,208-215,x;y;text sequence causes the printer driver's
- current graphics position to be updated. Again, application writers are
- strongly recommended to use the font manager SWIs in preference to these VDU
- sequences.
-
-
-
- SPRITE OPERATIONS
- =================
-
-
- Printer drivers intercept OS_SpriteOp via the SpriteV vector. Most calls are
- simply passed through to the operating system or the SpriteExtend module. The
- ones that normally plot to the screen are generally intercepted and used to
- generate printer output by the printer driver.
-
- The following reason codes normally involve reading or writing the screen
- contents and are not straightforward sprite plotting operations. Because some
- printer drivers redirect output to a sprite internally, it is unknown what
- the "screen" is during these operations. They are therefore faulted.
-
- 2 - screen save
- 3 - screen load
- 14 - get sprite from current point on screen
- 16 - get sprite from specified point on screen
-
- Reason codes that are passed through to the operating system or the
- SpriteExtend module are:
-
- 8 - read sprite area control block
- 9 - initialise sprite area
- 10 - load sprite file
- 11 - merge sprite file
- 12 - save sprite file
- 13 - return name of numbered sprite
- 15 - create sprite
- 25 - delete sprite
- 26 - rename sprite
- 27 - copy sprite
- 29 - create mask
- 30 - remove mask
- 31 - insert row
- 32 - delete row
- 33 - flip about X axis
- 35 - append sprite
- 36 - set pointer shape
- 40 - read sprite size
- 41 - read pixel colour
- 42 - write pixel colour
- 43 - read pixel mask
- 44 - write pixel mask
- 45 - insert column
- 46 - delete column
- 47 - flip about Y axis
- 62 - read save area size
-
- The following reason code is passed through to the operating system. In
- addition, the printer driver remembers the sprite selected so that VDU
- 25,232-239,x;y; sequences can be correctly converted to SWI OS_SpriteOp
- calls.
-
- 24 - select sprite
-
- The following reason codes plot a sprite or its mask, and are converted into
- appropriate printer output:
-
- 28 - plot sprite at current point on screen
- 34 - plot sprite at specified point on screen
- 48 - plot mask at current point on screen
- 49 - plot mask at specified point on screen
- 50 - plot mask at specified point on screen, scaled
- 51 - plot character, scaled
- 52 - plot sprite at specified point on screen, scaled
- 53 - plot sprite at specified point on screen, grey scaled
-
- As usual for a printer driver, only some GCOL actions are understood. If the
- GCOL action is not divisible by 8, nothing is plotted. If it is divisible by
- 8, the "overwrite" action is used. If it is divisible by 16, the sprite is
- plotted without using its mask; otherwise the mask is used.
-
- The colours used to plot sprite pixels are determined as follows:
-
- * If the call does not allow a pixel translation table, or if no
- translation table is supplied, the current screen palette is consulted to
- find out what RGB combination the sprite pixel's value corresponds to.
- The printer driver then does its best to produce that RGB combination.
- Use of this option is not really recommended.
- * If a translation table is supplied with the call, the printer driver
- assumes that the table contains code values allocated by one of:
-
- SWI ColourTrans_SelectTable with R2 = -1
- SWI ColourTrans_ReturnColourNumber
- SWI ColourTrans_ReturnColourNumberForMode with R1 = -1
- SWI ColourTrans_ReturnOppColourNumber
- SWI ColourTrans_ReturnOppColourNumberForMode with R1 = -1
-
- It can therefore look up precisely which RGB combination is supposed to
- correspond to each sprite pixel value. Because of the variety of ways in
- which printer drivers can allocate these values, the translation table
- should always have been set up in the current print job and using these
- calls.
-
- If a sprite is printed unscaled, its size on the printed output is the same
- as its size would be if it were plotted to the screen in the screen mode that
- was in effect at the time that the print job concerned was started. If it is
- printed scaled, the scaling factors are applied to this size. This is one of
- the few ways in which the printed output does depend on this screen mode (the
- main other ones are in interpreting GCOL and TINT values, and in interpreting
- VDU 5 character sizes). It is done this way in the expectation that the
- application is scaling the sprite for what it believes is the current screen
- mode.
-
- Finally, the following two reason codes are intercepted to keep track of
- whether plotting output is currently supposed to go to a sprite or to the
- screen. If it is supposed to go to a sprite, it really will go to that sprite
- - this allows applications to create sprites normally while printing. If it
- is supposed to go to the screen, it will be processed by the printer driver.
- (Note that printer drivers that redirect output to a sprite internally will
- treat this case specially, regarding output as still being destined for the
- screen!)
-
- 60 - switch output to sprite
- 61 - switch output to mask
-
-
-
- DRAW MODULE CALLS
- =================
-
-
- Printer drivers intercept the DrawV vector and re-interpret those calls whose
- purpose is to plot something on the screen, producing appropriate printer
- output instead. There are a number of restrictions on the calls that can be
- dealt with, mainly due to the limitations of PostScript. Most of the
- operations that are disallowed are not particularly useful, fortunately.
-
- Note that the Draw module calls normally use the graphics foreground colour
- to plot with and the graphics origin. The printer driver uses its versions of
- these values. In particular, this means that the fill colour is subject to
- all the restrictions noted elsewhere in this document.
-
- The floating point Draw module calls are not intercepted at present. If and
- when the Draw module is upgraded to deal with them, printer drivers will be
- similarly upgraded.
-
-
- SWI Draw_Fill
- -------------
-
- Printer drivers can deal with most common calls to this SWI. The
- restrictions are:
-
- (a) They cannot deal with fill styles that invoke the positive or negative
- winding number rules - i.e. those with bit 0 set.
- (b) They cannot deal with a fill style which asks for non-boundary exterior
- pixels to be plotted (i.e. which have bit 2 set). Exception: they can
- deal with the trivial case in which all of bits 2-5 are set - i.e. if
- all pixels in the plane are to be plotted!
- (c) They cannot deal with the following values for bits 5-2:
- 0010 - plot exterior boundary pixels only.
- 0100 - plot interior boundary pixels only.
- 1010 - plot exterior boundary and interior non-boundary pixels only.
- (d) An application should not rely on there being any difference between
- what is printed for the following three values of bits 5-2:
- 1000 - plot interior non-boundary pixels only.
- 1100 - plot all interior pixels.
- 1110 - plot all interior pixels and exterior boundary pixels.
- (A printer driver will generally try its best to distinguish these, but
- it may not be possible.)
-
-
- SWI Draw_Stroke
- ---------------
-
- Again, most common calls to this SWI can be dealt with. The restrictions
- on the parameters depend on whether the specified thickness is zero or not:
-
- If the specified thickness is zero, the restrictions are:
-
- (a) Printer drivers cannot deal with a fill style with bits 3-2 equal to 01
- - i.e. one that asks for pixels lying on the stroke to be plotted and
- those that lie off the stroke not to be.
- (b) Most printer drivers will not pay any attention to bit 31 of the fill
- style - the one that distinguishes plotting the stroke subpath by
- subpath from plotting it all at once.
-
- If the specified thickness is non-zero, the restrictions are:
-
- (a) All the restrictions mentioned under SWI Draw_Fill above.
- (b) They cannot deal with bits 5-2 being 0110 - i.e. asking for just the
- boundary pixels of the resulting filled path to be plotted.
- (c) Most printer drivers will not pay any attention to bit 31 of the fill
- style - the one that distinguishes plotting the stroke subpath by
- subpath from plotting it all at once.
-
-
- SWI Draw_StrokePath, SWI Draw_FlattenPath and SWI Draw_TransformPath
- --------------------------------------------------------------------
-
- None of these do any plotting; they are all dealt with in the normal way by
- the Draw module.
-
-
- SWI Draw_ProcessPath
- --------------------
-
- This SWI is faulted if R7=1 (fill path normally) or R7=2 (fill path subpath
- by subpath) on entry. Use the appropriate one of Draw_Fill or Draw_Stroke if
- you want to produce printed output. If the operation you're trying to do is
- too complicated for them, it almost certainly cannot be handled by e.g. the
- PostScript printer driver.
-
- All other values of R7 correspond to calls that don't do any plotting and are
- dealt with in the normal way by the Draw module. If you're trying to do
- something complicated and you've got enough workspace and RMA, a possible
- useful trick is to use SWI Draw_ProcessPath with R7 pointing to an output
- buffer, followed by SWI Draw_Fill on the result.
-
-
-
- COLOURTRANS MODULE CALLS
- ========================
-
-
- The printer driver intercepts calls to the ColourTrans module, via the
- ColourV vector. Most of them are passed straight on to the ColourTrans module
- - the exceptions are:
-
-
- SWI ColourTrans_SelectTable with R2 = -1
- ----------------------------------------
-
- Each RGB combination in the source palette (or implied by it in the case of
- 256 colour modes) is converted into a colour number as though by SWI
- ColourTrans_ReturnColourNumber (see below). The resulting values are placed
- in the table.
-
-
- SWI ColourTrans_SetGCOL
- -----------------------
-
- The printer driver's version of the foreground or background colour (as
- appropriate) is set. The GCOL actions are interpreted precisely as for the
- VDU 18,k,c call (see above). However, rather than looking up a GCOL in the
- screen palette at plot time, the exact RGB combination specified in this call
- is remembered and used (as accurately as the printer will render it) at plot
- time.
-
- After this has been done, the call is effectively converted into SWI
- ColourTrans_ReturnGCOL and passed down to the ColourTrans module in order to
- set the information returned correctly. Note that this implies that
- subsequently using the GCOL returned in a VDU 18,k,c sequence will not
- produce the same effect on the colour as this call: it will merely produce
- the best approximation the printer can manage to the best approximation the
- current screen palette can manage to the specified RGB combination. It is
- therefore probably a bad idea to use the values returned.
-
- This call therefore allows the application to make full use of a printer's
- colour resolution without having to switch to another screen mode or mess
- around with the screen's palette, and without worrying about the effects of a
- change in the screen's palette. It is therefore the recommended way to set
- the foreground and background colours.
-
-
- SWI ColourTrans_ReturnColourNumber
- ----------------------------------
-
- This will return a code value (in the range 0-255) that identifies the
- specified RGB combination as accurately as possible to the printer driver.
- How this code value is determined may vary from printer driver to printer
- driver, and indeed even from print job to print job for the same printer
- driver. An application should therefore not make any assumptions about what
- these code values mean.
-
- (Most printer drivers implement this by pre-allocating some range of code
- values to evenly spaced RGB combinations, then adopting the following
- approach:
-
- (a) If the RGB combination is already known about, return the
- corresponding code value.
- (b) If the RGB combination is not already known about and some code values
- are still free, allocate one of the unused code values to the new RGB
- combination and return that code value.
- (c) If the RGB combination is not already known about and all code values
- have been allocated, return the code number whose RGB combination is
- as close as possible to the desired RGB combination.
-
- The pre-allocation of evenly spaced RGB combinations will ensure that even
- case (c) does not have really terrible results.)
-
-
- SWI ColourTrans_ReturnColourNumberForMode with R1 = -1
- ------------------------------------------------------
-
- This is treated exactly the same as SWI ColourTrans_ReturnColourNumber above.
-
-
- SWI ColourTrans_SetOppGCOL
- --------------------------
-
- This behaves like ColourTrans_SetGCOL above, except that the RGB combination
- it remembers is the furthest possible RGB combination from the one actually
- specified in R0, and it ends by being converted into a call to
- ColourTrans_ReturnOppGCOL. Note that there is no guarantee that the GCOL
- returned is anywhere near the RGB combination remembered!
-
-
- SWI ColourTrans_ReturnOppColourNumber
- -------------------------------------
-
- This behaves exactly as though ColourTrans_ReturnColourNumber (see above) had
- been called with R0 containing the furthest possible RGB combination from the
- one actually specified.
-
-
- SWI ColourTrans_ReturnOppColourNumberForMode with R1 = -1
- ---------------------------------------------------------
-
- This behaves exactly as though ColourTrans_ReturnColourNumberForMode (see
- above) had been called with R1 = -1 and R0 containing the furthest possible
- RGB combination from the one actually specified.
-
-
- SWI ColourTrans_SetFontColours
- ------------------------------
-
- The printer driver's version of the font colours is set, to as accurate a
- representation of the desired RGB combinations as the printer can manage.
-
- After this has been done, the call is effectively converted into SWI
- ColourTrans_ReturnFontColours and passed down to the ColourTrans module in
- order to set the information returned correctly. Note that this implies that
- subsequently using the values returned in a SWI Font_SetFontColours call will
- not produce the same effect on the font colours as this call: it will merely
- produce the best approximations the printer can manage to the best
- approximations the current screen palette can manage to the specified RGB
- combinations. It is therefore probably a bad idea to use the values returned.
-
- This call therefore allows the application to make full use of a printer's
- colour resolution without having to switch to another screen mode or mess
- around with the screen's palette, and without worrying about the effects of a
- change in the screen's palette. It is the recommended way to set the font
- colours.
-
-
-
- FONT MANAGER CALLS
- ==================
-
-
- The printer driver interacts with the font manager (via a service call and
- SWI PDriver_FontSWI) in such a way that when it is active, calls to the
- following SWIs are processed by the printer driver:
-
- SWI Font_Paint
- SWI Font_LoseFont
- SWI Font_SetFontColours
- SWI Font_SetPalette
-
- This enables the printer driver to make SWI Font_Paint produce printer output
- rather than affecting the screen.
-
- The use of SWI Font_SetFontColours is not recommended, as it results in the
- setting of colours that depend on the current screen palette. Instead, use
- SWI ColourTrans_SetFontColours to set font colours to absolute RGB values.
- Similarly, the use of colour-changing control sequences in strings passed to
- SWI Font_Paint is not recommended.
-
- In addition to the control sequences allowed by current font managers,
- printer drivers will be able to handle the following control sequence if
- the font manager they are working with can:
-
- 19,background red,green,blue,foreground red,green,blue,maximum offset
-
- This gives a way of changing colour in the middle of a string without
- sacrificing colour resolution.
-
- (How exactly it does this varies quite markedly between printer drivers: for
- instance, most dot matrix printer drivers will probably use the font manager
- to write into the sprite they are using to hold the current strip of printed
- output, while the PostScript printer driver uses the PostScript prologue to
- define a translation from font manager font names to printer fonts.)
-
-
-
- MISCELLANEOUS CALLS
- ===================
-
-
- OS_Byte 163,242,0-64 are intercepted to set the printer driver version of the
- dot pattern repeat length instead of the VDU drivers' version.
-
- OS_Byte 218 is intercepted to act on the printer driver's VDU queue instead
- of the VDU drivers' version.
-
- It should be noted that most of the informational calls associated with the
- VDU drivers (and OS_ReadVduVariables in particular) will produce undefined
- results when a printer driver is active. These results are likely to differ
- between printer drivers (in particular, they will vary according to whether
- the printer driver plots to a sprite internally and if so, how large the
- sprite concerned is).
-
- The only informational calls that the application may rely upon are:
-
- OS_Word 10 - used to read character and ECF definitions.
- OS_Word 11 - used to read palette definitions.
- OS_ReadPalette - used to read palette definitions.
- OS_Byte 218 - when used to read the number of bytes in the VDU queue.
-